home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Resources / Online / Term / Extras / Source / term-source.lha / StatusDisplay.c < prev    next >
C/C++ Source or Header  |  1996-10-20  |  29KB  |  1,324 lines

  1. /*
  2. **    StatusDisplay.c
  3. **
  4. **    Status information display routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16.     /* The information to be displayed. */
  17.  
  18. enum    {
  19.             INFO_STATUS,INFO_BUFFER,INFO_PROTOCOL,INFO_EMULATION,INFO_BAUDRATE,
  20.             INFO_PARAMETERS,INFO_CURRENTTIME,INFO_ONLINETIME,INFO_ONLINECOST,
  21.             INFO_UNITTIME
  22.         };
  23.  
  24.     /* The current status line display mode. */
  25.  
  26. enum    {
  27.             MODE_SCREEN_NORMAL,MODE_SCREEN_COMPRESSED,
  28.             MODE_WB_NORMAL,MODE_WB_COMPRESSED
  29.         };
  30.  
  31.     /* Enumerated text boxes. */
  32.  
  33. enum    {
  34.             STATUSBOX_STATUS_FONT,STATUSBOX_PROTOCOL_TERMINAL,
  35.             STATUSBOX_RATE_PARAMETERS,STATUSBOX_TIME_ONLINE
  36.         };
  37.  
  38.     /* What to show in the online time box. */
  39.  
  40. enum    {
  41.             SHOW_Cost,SHOW_OnlineTime,SHOW_UnitTime
  42.         };
  43.  
  44.     /* The status server passes this structure to the
  45.      * rendering routine if the status information
  46.      * is to be updated.
  47.      */
  48.  
  49. struct ObjectCarrier
  50. {
  51.     struct RastPort     *RPort;
  52.     LONG              FirstColumn,
  53.                       FullWidth;
  54.     struct TextBox    **BoxArray,
  55.                      *BoxList;
  56. };
  57.  
  58.     /* A custom message type for the display update server. */
  59.  
  60. struct UpdateMessage
  61. {
  62.     struct Message    Message;
  63.  
  64.     APTR            Object;
  65.     UBYTE            Mode,
  66.                     Type;
  67. };
  68.  
  69.     /* The following static strings are displayed in the status
  70.      * window.
  71.      */
  72.  
  73. STATIC STRPTR             ConfigBufferState[3],
  74.                          ConfigEmulation[6],
  75.                          ConfigParity[6];
  76.  
  77.     /* The status modes and the corresponding text IDs. */
  78.  
  79. STATIC LONG ConfigStatusIDs[] =
  80. {
  81.     MSG_TERMAUX_READY_TXT,
  82.     MSG_TERMAUX_HOLDING_TXT,
  83.     MSG_TERMAUX_DIALING_TXT,
  84.     MSG_TERMAUX_UPLOAD_TXT,
  85.     MSG_TERMAUX_DOWNLOAD_TXT,
  86.     MSG_TERMAUX_BREAKING_TXT,
  87.     MSG_TERMAUX_HANG_UP_TXT,
  88.     MSG_TERMAUX_RECORD_TXT,
  89.     MSG_AREXX_RUNNING_TXT
  90. };
  91.  
  92.     /* Width of the status line text, required in case the user interface
  93.      * font happens to be proportional-spaced.
  94.      */
  95.  
  96. STATIC LONG                 StatusLineWidth;
  97.  
  98.     /* The status display update task. */
  99.  
  100. STATIC struct Task        *StatusDisplayTask;
  101. STATIC struct MsgPort    *StatusDisplayPort;
  102.  
  103.     /* Display update data */
  104.  
  105. STATIC WORD                 UpdateSig;
  106. STATIC ULONG             UpdateMask;
  107. STATIC BOOL                 NeedFullRefresh;
  108.  
  109. STATIC VOID
  110. DrawSeparator(struct RastPort *RPort)
  111. {
  112.     SetAPen(RPort,Pens[SHADOWPEN]);
  113.     RectFill(RPort,StatusDisplayLeft,StatusDisplayTop,StatusDisplayLeft + StatusDisplayWidth - 1,StatusDisplayTop);
  114.  
  115.     SetAPen(RPort,Pens[SHINEPEN]);
  116.     RectFill(RPort,StatusDisplayLeft,StatusDisplayTop + 1,StatusDisplayLeft + StatusDisplayWidth - 1,StatusDisplayTop + 1);
  117. }
  118.  
  119.     /* DoStatusInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String):
  120.      *
  121.      *    Display information in the status line area.
  122.      */
  123.  
  124. STATIC VOID
  125. DoStatusInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String)
  126. {
  127.         /* What mode of operation is the status area in? */
  128.  
  129.     switch(Mode)
  130.     {
  131.             /* Compressed mode. */
  132.  
  133.         case MODE_SCREEN_COMPRESSED:
  134.         {
  135.             struct RastPort *RPort = Object;
  136.  
  137.             STATIC BYTE Offsets[8] =
  138.             {
  139.                  0,
  140.                 -1,    /* Not supported */
  141.                 26,
  142.                 11,
  143.                 40,
  144.                 53,
  145.                 61,
  146.                 72
  147.             };
  148.  
  149.             STATIC UBYTE Strings[8][20];
  150.             UBYTE LineBuffer[90];
  151.             LONG i,j,k,Width;
  152.  
  153.             strcpy(Strings[Type],String);
  154.  
  155.             strcpy(LineBuffer,"         ·              ·             ·            ·       ·          ·         ");
  156.  
  157.             for(i = 0 ; i < 8 ; i++)
  158.             {
  159.                 if(Offsets[i] >= 0)
  160.                 {
  161.                     j = strlen(Strings[i]);
  162.  
  163.                     for(k = 0 ; k < j ; k++)
  164.                         LineBuffer[Offsets[i] + k] = Strings[i][k];
  165.                 }
  166.             }
  167.  
  168.             Width = TextLength(RPort,LineBuffer,80);
  169.  
  170.             if((StatusLineWidth && StatusLineWidth != Width) || NeedFullRefresh)
  171.             {
  172.                 LONG OldPen = ReadAPen(RPort);
  173.  
  174.                 SetAPen(RPort,Pens[TEXTPEN]);
  175.                 FillBox(RPort,StatusDisplayLeft,StatusDisplayTop,StatusDisplayWidth,StatusDisplayHeight);
  176.                 SetAPen(RPort,OldPen);
  177.  
  178.                 StatusLineWidth = Width;
  179.                 NeedFullRefresh = FALSE;
  180.             }
  181.  
  182.             PlaceText(RPort,StatusDisplayLeft + (StatusDisplayWidth - Width) / 2,StatusDisplayTop,LineBuffer,80);
  183.         }
  184.  
  185.         break;
  186.  
  187.             /* Normal mode. */
  188.  
  189.         case MODE_SCREEN_NORMAL:
  190.         {
  191.             STATIC UBYTE Codes[8][2] =
  192.             {
  193.                 STATUSBOX_STATUS_FONT,            0,
  194.                 STATUSBOX_STATUS_FONT,            1,
  195.  
  196.                 STATUSBOX_PROTOCOL_TERMINAL,    0,
  197.                 STATUSBOX_PROTOCOL_TERMINAL,    1,
  198.  
  199.                 STATUSBOX_RATE_PARAMETERS,        0,
  200.                 STATUSBOX_RATE_PARAMETERS,        1,
  201.  
  202.                 STATUSBOX_TIME_ONLINE,            0,
  203.                 STATUSBOX_TIME_ONLINE,            1
  204.             };
  205.  
  206.             struct ObjectCarrier *Carrier = (struct ObjectCarrier *)Object;
  207.  
  208.             if(Carrier->RPort)
  209.             {
  210.                 if(NeedFullRefresh && !Config->ScreenConfig->SplitStatus)
  211.                 {
  212.                     struct RastPort    *RPort = Carrier->RPort;
  213.                     LONG             Left;
  214.  
  215.                     if((Left = StatusDisplayLeft + (StatusDisplayWidth - Carrier->FullWidth) / 2) < 0)
  216.                         Left = 0;
  217.  
  218.                     Left += Carrier->FirstColumn - SZ_GetBoxInfo(Carrier->BoxList,BOX_LEFT);
  219.  
  220.                     SetAPen(RPort,Pens[BACKGROUNDPEN]);
  221.                     FillBox(RPort,StatusDisplayLeft,StatusDisplayTop,StatusDisplayWidth,StatusDisplayHeight);
  222.  
  223.                     DrawSeparator(RPort);
  224.  
  225.                     SZ_SetBoxes(Carrier->BoxList,-1,StatusDisplayTop + 3);
  226.                     SZ_MoveBoxes(Carrier->BoxList,Left,0);
  227.  
  228.                     SZ_DrawBoxes(RPort,Carrier->BoxList);
  229.  
  230.                     NeedFullRefresh = FALSE;
  231.                 }
  232.  
  233.                 SZ_PrintLine(Carrier->RPort,Carrier->BoxArray[Codes[Type][0]],Codes[Type][1],String);
  234.             }
  235.         }
  236.  
  237.         break;
  238.     }
  239. }
  240.  
  241.     /* DoInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String):
  242.      *
  243.      *    Post an update message to the status display server.
  244.      */
  245.  
  246. STATIC VOID
  247. DoInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String)
  248. {
  249.     struct UpdateMessage    *Msg;
  250.     LONG                     Len = strlen(String) + 1;
  251.  
  252.         /* Allocate enough space to hold both the string
  253.          * and the message.
  254.          */
  255.  
  256.     if(Msg = (struct UpdateMessage *)AllocVecPooled(sizeof(struct UpdateMessage) + Len,MEMF_ANY | MEMF_CLEAR))
  257.     {
  258.             /* Fill in the message head. */
  259.  
  260.         Msg->Message.mn_Length = sizeof(struct UpdateMessage) + Len;
  261.  
  262.             /* Set up the name pointer. */
  263.  
  264.         Msg->Message.mn_Node.ln_Name = (STRPTR)(Msg + 1);
  265.  
  266.             /* Copy the string. */
  267.  
  268.         strcpy(Msg->Message.mn_Node.ln_Name,String);
  269.  
  270.             /* Fill in the remaining data. */
  271.  
  272.         Msg->Object    = Object;
  273.         Msg->Mode        = Mode;
  274.         Msg->Type        = Type;
  275.  
  276.             /* Post the message. */
  277.  
  278.         PutMsg(StatusDisplayPort,(struct Message *)Msg);
  279.     }
  280. }
  281.  
  282.     /* UpdateInfo(APTR Object,UBYTE Mode,UBYTE Type,...):
  283.      *
  284.      *    Update the information displayed in the status
  285.      *    area.
  286.      */
  287.  
  288. STATIC VOID
  289. UpdateInfo(APTR Object,UBYTE Mode,UBYTE Type,...)
  290. {
  291.     if(Object)
  292.     {
  293.         UBYTE     MiniBuffer[50];
  294.         STRPTR    *String;
  295.         LONG    *Numeral;
  296.         va_list     VarArgs;
  297.  
  298.         va_start(VarArgs,Type);
  299.  
  300.         String    = (STRPTR *)VarArgs;
  301.         Numeral    = (LONG *)VarArgs;
  302.  
  303.         switch(Type)
  304.         {
  305.             case INFO_STATUS:
  306.  
  307.                 LimitedStrcpy(sizeof(MiniBuffer),MiniBuffer,LocaleString(ConfigStatusIDs[Numeral[0]]));
  308.                 LimitedStrcat(sizeof(MiniBuffer),MiniBuffer,"         ");
  309.  
  310.                 MiniBuffer[9] = 0;
  311.  
  312.                 break;
  313.  
  314.             case INFO_BUFFER:
  315.  
  316.                 if(Mode == MODE_SCREEN_NORMAL)
  317.                     DoInfo(Object,Mode,Type,ConfigBufferState[Numeral[0]]);
  318.  
  319.                 va_end(VarArgs);
  320.  
  321.                 return;
  322.  
  323.             case INFO_UNITTIME:
  324.  
  325.                 LimitedSPrintf(sizeof(MiniBuffer) - 1,&MiniBuffer[1],"%2ld:%02ld",Numeral[0] / 60,Numeral[0] % 60);
  326.  
  327.                 if(Numeral[0] > 0)
  328.                     MiniBuffer[0] = '-';
  329.                 else
  330.                     MiniBuffer[0] = ' ';
  331.  
  332.                 Type = INFO_ONLINETIME;
  333.  
  334.                 break;
  335.  
  336.             case INFO_ONLINECOST:
  337.  
  338.                 CopyMem(String[0],MiniBuffer,8);
  339.                 LimitedStrcat(sizeof(MiniBuffer),MiniBuffer,"          ");
  340.  
  341.                 MiniBuffer[8] = 0;
  342.  
  343.                 Type = INFO_ONLINETIME;
  344.  
  345.                 break;
  346.  
  347.             case INFO_CURRENTTIME:
  348.  
  349.                 FormatTime(MiniBuffer,sizeof(MiniBuffer),Numeral[0],Numeral[1],Numeral[2]);
  350.                 break;
  351.  
  352.             case INFO_ONLINETIME:
  353.  
  354.                 LimitedSPrintf(sizeof(MiniBuffer),MiniBuffer,"%02ld:%02ld:%02ld",Numeral[0],Numeral[1],Numeral[2]);
  355.                 break;
  356.  
  357.             case INFO_BAUDRATE:
  358.  
  359.                 if(LocaleBase)
  360.                     LimitedSPrintf(sizeof(MiniBuffer),MiniBuffer,"%lD        ",Numeral[0]);
  361.                 else
  362.                     LimitedSPrintf(sizeof(MiniBuffer),MiniBuffer,"%ld        ",Numeral[0]);
  363.  
  364.                 MiniBuffer[7] = 0;
  365.  
  366.                 break;
  367.  
  368.             case INFO_PROTOCOL:
  369.             case INFO_EMULATION:
  370.  
  371.                 CopyMem(String[0],MiniBuffer,12);
  372.                 LimitedStrcat(sizeof(MiniBuffer),MiniBuffer,"           ");
  373.  
  374.                 MiniBuffer[12] = 0;
  375.  
  376.                 break;
  377.  
  378.             case INFO_PARAMETERS:
  379.  
  380.                 if(Mode == MODE_SCREEN_COMPRESSED)
  381.                 {
  382.                     STATIC UBYTE Parities[5] =
  383.                     {
  384.                         'N','E','O','M','S'
  385.                     };
  386.  
  387.                     LimitedSPrintf(sizeof(MiniBuffer),MiniBuffer,"%ld-%lc-%ld",Numeral[0],Parities[Numeral[1]],Numeral[2]);
  388.                 }
  389.                 else
  390.                     LimitedSPrintf(sizeof(MiniBuffer),MiniBuffer,"%ld-%s-%ld",Numeral[0],ConfigParity[Numeral[1]],Numeral[2]);
  391.  
  392.                 break;
  393.         }
  394.  
  395.         DoInfo(Object,Mode,Type,MiniBuffer);
  396.  
  397.         va_end(VarArgs);
  398.     }
  399. }
  400.  
  401.     /* VisualBeep():
  402.      *
  403.      *    Handle the visual part of the display beep.
  404.      */
  405.  
  406. STATIC BOOL
  407. VisualBeep(ColourTable **OldPtr,ColourTable **NewPtr)
  408. {
  409.     ColourTable *Old,*New;
  410.  
  411.     Old = CreateColourTable(Window->WScreen->ViewPort.ColorMap->Count,NULL,NULL);
  412.     New = CreateColourTable(Window->WScreen->ViewPort.ColorMap->Count,NULL,NULL);
  413.  
  414.     if(New && Old)
  415.     {
  416.         ULONG Red,Green,Blue;
  417.         LONG i;
  418.  
  419.         GrabColours(&Window->WScreen->ViewPort,Old);
  420.         CopyColours(Old,New);
  421.  
  422.         for(i = 0 ; i < Old->NumColours ; i++)
  423.         {
  424.             Red        = (Old->Entry[i].Red     >> 24) + 64;
  425.             Green    = (Old->Entry[i].Green     >> 24) + 64;
  426.             Blue    = (Old->Entry[i].Blue     >> 24) + 64;
  427.  
  428.             if(Red > 255)
  429.                 Red = 255;
  430.  
  431.             if(Green > 255)
  432.                 Green = 255;
  433.  
  434.             if(Blue > 255)
  435.                 Blue = 255;
  436.  
  437.             New->Entry[i].Red    = SPREAD(Red);
  438.             New->Entry[i].Green    = SPREAD(Green);
  439.             New->Entry[i].Blue    = SPREAD(Blue);
  440.         }
  441.  
  442.         *OldPtr = Old;
  443.         *NewPtr = New;
  444.  
  445.         return(TRUE);
  446.     }
  447.  
  448.     DeleteColourTable(Old);
  449.     DeleteColourTable(New);
  450.  
  451.     *OldPtr = *NewPtr = NULL;
  452.  
  453.     return(FALSE);
  454. }
  455.  
  456.     /* StatusDisplayServer(VOID):
  457.      *
  458.      *    Yet another asynchronous background task to display
  459.      *    some information.
  460.      */
  461.  
  462. STATIC VOID SAVE_DS
  463. StatusDisplayServer(VOID)
  464. {
  465.         /* Create the interface port. */
  466.  
  467.     if(StatusDisplayPort = CreateMsgPort())
  468.     {
  469.         struct UpdateMessage    *Msg;
  470.         ULONG                     Signals;
  471.  
  472.             /* Ring back... */
  473.  
  474.         Signal((struct Task *)StatusProcess,SIG_HANDSHAKE);
  475.  
  476.             /* Wait for messages or termination signal. */
  477.  
  478.         FOREVER
  479.         {
  480.             Signals = Wait(SIG_KILL | PORTMASK(StatusDisplayPort));
  481.  
  482.                 /* Termination? */
  483.  
  484.             if(Signals & SIG_KILL)
  485.                 break;
  486.  
  487.                 /* Message arrival? */
  488.  
  489.             if(Signals & PORTMASK(StatusDisplayPort))
  490.             {
  491.                     /* Process all pending messages. */
  492.  
  493.                 while(Msg = (struct UpdateMessage *)GetMsg(StatusDisplayPort))
  494.                 {
  495.                     DoStatusInfo(Msg->Object,Msg->Mode,Msg->Type,Msg->Message.mn_Node.ln_Name);
  496.  
  497.                     FreeVecPooled(Msg);
  498.                 }
  499.             }
  500.         }
  501.  
  502.             /* Remove all pending messages. */
  503.  
  504.         while(Msg = (struct UpdateMessage *)GetMsg(StatusDisplayPort))
  505.             FreeVecPooled(Msg);
  506.  
  507.             /* Remove the msgport. */
  508.  
  509.         DeleteMsgPort(StatusDisplayPort);
  510.     }
  511.  
  512.         /* Lock & quit... */
  513.  
  514.     Forbid();
  515.  
  516.     StatusDisplayTask = NULL;
  517.  
  518.     Signal((struct Task *)StatusProcess,SIG_HANDSHAKE);
  519.  
  520.     RemTask(NULL);
  521. }
  522.  
  523.     /* StatusServer():
  524.      *
  525.      *    Asynchronous process to continuosly display the current
  526.      *    terminal settings.
  527.      */
  528.  
  529. VOID SAVE_DS
  530. StatusServer()
  531. {
  532.     STATIC struct timeval     OnlineTime,
  533.                              DeltaTime,
  534.                              LastTime,
  535.                              PeriodTime;
  536.     STATIC LONG                 BeepCount;
  537.  
  538.     STATIC BOOL                 LocalWasOnline;
  539.  
  540.     BOOL                     LocalIsOnline;
  541.  
  542.     BOOL                     PeriodAction;
  543.  
  544.     struct TextBox            *BoxArray[4],
  545.                             *BoxList = NULL,
  546.                             *Box;
  547.  
  548.     struct RastPort            *RPort;
  549.  
  550.     APTR                     SomeObject;
  551.     struct ObjectCarrier     Carrier;
  552.  
  553.     struct timerequest        *StatusTimeRequest;
  554.     struct MsgPort            *StatusTimePort;
  555.     struct timeval             Now;
  556.  
  557.     BOOL                     Background            = FALSE,
  558.                              FlashIt            = FALSE,
  559.                              SetColours            = FALSE,
  560.                              StandardColours    = TRUE,
  561.                              KeepGoing            = TRUE,
  562.                              Beeping            = FALSE;
  563.  
  564.     WORD                     StatusMode            = Config->ScreenConfig->StatusLine;
  565.     WORD                     ShowCounter        = 0;
  566.  
  567.     UBYTE                     LastProtocol[MAX_FILENAME_LENGTH],
  568.                              LastEmulationName[MAX_FILENAME_LENGTH];
  569.  
  570.     LONG                     LastFrozen            = -1,
  571.                              LastEmulation        = -1,
  572.                              LastBitsPerChar    = -1,
  573.                              LastParity            = -1,
  574.                              LastStopBits        = -1,
  575.                              LastStatus            = -1;
  576.  
  577.     LONG                     LastBaud            = -1;
  578.  
  579.     LONG                     i,
  580.                              ThisHour,
  581.                              ThisMinute,
  582.                              BoxCounter = 0,
  583.                              FullWidth;
  584.     LONG                     ColumnLeft[4],
  585.                              ColumnWidth[4],
  586.                              Max,
  587.                              Len;
  588.  
  589.     ColourTable                *Old = NULL,
  590.                             *New = NULL;
  591.  
  592.     BOOL                     AllFine = TRUE;
  593.     LONG                     Mode;
  594.  
  595.     StatusLineWidth = 0;
  596.  
  597.     LastProtocol[0] = 0;
  598.  
  599.     LastEmulationName[0] = 0;
  600.  
  601.     LocalizeString(ConfigBufferState,MSG_TERMSTATUSDISPLAY_FROZEN_TXT,MSG_TERMSTATUSDISPLAY_RECORDING_TXT);
  602.     LocalizeString(ConfigEmulation,MSG_TERMAUX_ANSI_VT102_TXT,MSG_TERMAUX_HEX_TXT);
  603.     LocalizeString(ConfigParity,MSG_TERMAUX_NONE_TXT,MSG_TERMAUX_SPACE_TXT);
  604.  
  605.     if(StatusWindow)
  606.         RPort = StatusWindow->RPort;
  607.     else
  608.         RPort = StatusRPort;
  609.  
  610.     if(RPort)
  611.     {
  612.         SetAPen(RPort,Pens[BACKGROUNDPEN]);
  613.         FillBox(RPort,StatusDisplayLeft,StatusDisplayTop,StatusDisplayWidth,StatusDisplayHeight);
  614.  
  615.             /* Render the information. */
  616.  
  617.         if(StatusWindow)
  618.             SZ_SizeSetup(StatusWindow->WScreen,(struct TextAttr *)&UserFont);
  619.         else
  620.             SZ_SizeSetup(Window->WScreen,(struct TextAttr *)&UserFont);
  621.  
  622.         if(StatusMode == STATUSLINE_COMPRESSED)
  623.         {
  624.             StatusOffset = (StatusDisplayWidth - 80 * UserFontWidth) / 2;
  625.  
  626.             SetAPen(RPort,Pens[TEXTPEN]);
  627.             FillBox(RPort,StatusDisplayLeft,StatusDisplayTop,StatusDisplayWidth,StatusDisplayHeight);
  628.  
  629.             SetPens(RPort,Pens[BACKGROUNDPEN],Pens[TEXTPEN],JAM2);
  630.  
  631.             SetFont(RPort,UserTextFont);
  632.         }
  633.         else
  634.         {
  635.             SetBPen(RPort,Pens[BACKGROUNDPEN]);
  636.  
  637.                 /* Draw a separating line. */
  638.  
  639.             if(!Config->ScreenConfig->SplitStatus)
  640.                 DrawSeparator(RPort);
  641.  
  642.             SetAPen(RPort,Pens[TEXTPEN]);
  643.  
  644.             ColumnLeft[0] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_STATUS_TXT,MSG_TERMSTATUSDISPLAY_FONT_TXT,-1);
  645.             ColumnLeft[1] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_PROTOCOL_TXT,MSG_TERMSTATUSDISPLAY_TERMINAL_TXT,-1);
  646.             ColumnLeft[2] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_BAUDRATE_TXT,MSG_TERMSTATUSDISPLAY_PARAMETERS_TXT,-1);
  647.             ColumnLeft[3] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_TIME_TXT,MSG_TERMSTATUSDISPLAY_ONLINE_TXT,-1);
  648.  
  649.             Max = 0;
  650.  
  651.             for(i = 0 ; i < NUM_ELEMENTS(ConfigStatusIDs) ; i++)
  652.             {
  653.                 if((Len = SZ_BoxWidth(strlen(LocaleString(ConfigStatusIDs[i])))) > Max)
  654.                     Max = Len;
  655.             }
  656.  
  657.             for(i = 0 ; ConfigBufferState[i] ; i++)
  658.             {
  659.                 if((Len = SZ_BoxWidth(strlen(ConfigBufferState[i]))) > Max)
  660.                     Max = Len;
  661.             }
  662.  
  663.             ColumnWidth[0] = Max;
  664.  
  665.             Max = SZ_BoxWidth(12);
  666.  
  667.             for(i = 0 ; ConfigEmulation[i] ; i++)
  668.             {
  669.                 if((Len = SZ_BoxWidth(strlen(ConfigEmulation[i]))) > Max)
  670.                     Max = Len;
  671.             }
  672.  
  673.             ColumnWidth[1] = Max;
  674.  
  675.             Max = SZ_BoxWidth(10);
  676.  
  677.             for(i = 0 ; ConfigParity[i] ; i++)
  678.             {
  679.                 if((Len = SZ_BoxWidth(4 + strlen(ConfigParity[i]))) > Max)
  680.                     Max = Len;
  681.             }
  682.  
  683.             ColumnWidth[2] = Max;
  684.  
  685.             ColumnWidth[3] = SZ_BoxWidth(8);
  686.  
  687.             FullWidth = 0;
  688.  
  689.             for(i = 0 ; i < 4 ; i++)
  690.                 FullWidth += ColumnWidth[i] + ColumnLeft[i];
  691.  
  692.             FullWidth += 4 + 3 * InterWidth;
  693.  
  694.             Carrier.FullWidth    = FullWidth;
  695.             Carrier.FirstColumn    = ColumnLeft[0] + 2;
  696.  
  697.             if(!Config->ScreenConfig->SplitStatus)
  698.             {
  699.                 if(FullWidth > StatusDisplayWidth)
  700.                     SZ_SetLeftEdge(StatusDisplayLeft + ColumnLeft[0] + 2);
  701.                 else
  702.                     SZ_SetLeftEdge(StatusDisplayLeft + (StatusDisplayWidth - FullWidth) / 2 + ColumnLeft[0] + 2);
  703.  
  704.                 SZ_SetAbsoluteTop(StatusDisplayTop + 3);
  705.                 SZ_SetTopEdge(StatusDisplayTop + 3);
  706.             }
  707.             else
  708.             {
  709.                 SZ_SetLeftEdge(StatusDisplayLeft + ColumnLeft[0] + 2);
  710.  
  711.                 SZ_SetAbsoluteTop(StatusDisplayTop + 1);
  712.                 SZ_SetTopEdge(StatusDisplayTop + 1);
  713.             }
  714.  
  715.             SZ_SetWidth(ColumnWidth[0]);
  716.  
  717.             BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&BoxList,
  718.                 SZ_Lines,        2,
  719.                 SZ_AutoWidth,    TRUE,
  720.             TAG_DONE);
  721.  
  722.             SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_STATUS_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_FONT_TXT),NULL);
  723.  
  724.             SZ_SetWidth(ColumnWidth[1]);
  725.             SZ_AddLeftOffset(ColumnLeft[1]);
  726.  
  727.             BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&BoxList,
  728.                 SZ_Lines,        2,
  729.                 SZ_AutoWidth,    TRUE,
  730.                 SZ_NewColumn,    TRUE,
  731.             TAG_DONE);
  732.  
  733.             SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_PROTOCOL_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_TERMINAL_TXT),NULL);
  734.  
  735.             SZ_SetWidth(ColumnWidth[2]);
  736.             SZ_AddLeftOffset(ColumnLeft[2]);
  737.  
  738.             BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&BoxList,
  739.                 SZ_Lines,        2,
  740.                 SZ_AutoWidth,    TRUE,
  741.                 SZ_NewColumn,    TRUE,
  742.             TAG_DONE);
  743.  
  744.             SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_BAUDRATE_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_PARAMETERS_TXT),NULL);
  745.  
  746.             SZ_SetWidth(ColumnWidth[3]);
  747.             SZ_AddLeftOffset(ColumnLeft[3]);
  748.  
  749.             BoxArray[BoxCounter] = Box = SZ_CreateTextBox(&BoxList,
  750.                 SZ_Lines,        2,
  751.                 SZ_AutoWidth,    TRUE,
  752.                 SZ_NewColumn,    TRUE,
  753.             TAG_DONE);
  754.  
  755.             SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_TIME_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_ONLINE_TXT),NULL);
  756.  
  757.             if(!Box)
  758.                 AllFine = FALSE;
  759.             else
  760.                 SZ_DrawBoxes(RPort,BoxList);
  761.         }
  762.     }
  763.     else
  764.         AllFine = TRUE;
  765.  
  766.     if((UpdateSig = AllocSignal(-1)) == -1)
  767.         AllFine = FALSE;
  768.     else
  769.         UpdateMask = 1L << UpdateSig;
  770.  
  771.         /* Everything fine so far? */
  772.  
  773.     if(AllFine)
  774.     {
  775.         Forbid();
  776.  
  777.             /* Create the display server task. */
  778.  
  779.         if(StatusDisplayTask = LocalCreateTask("term Status Display Task",5,(TASKENTRY)StatusDisplayServer,4000,0))
  780.             WaitForHandshake();
  781.  
  782.         Permit();
  783.     }
  784.  
  785.         /* Is the display server task up and running? */
  786.  
  787.     if(StatusDisplayTask)
  788.     {
  789.             /* Create a timer device request. */
  790.  
  791.         if(StatusTimePort = (struct MsgPort *)CreateMsgPort())
  792.         {
  793.             if(StatusTimeRequest = (struct timerequest *)CreateIORequest(StatusTimePort,sizeof(struct timerequest)))
  794.             {
  795.                 if(!OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)StatusTimeRequest,0))
  796.                 {
  797.                         /* Signal our father process
  798.                          * that we're running.
  799.                          */
  800.  
  801.                     Signal((struct Task *)ThisProcess,SIG_HANDSHAKE);
  802.  
  803.                     if(RPort)
  804.                     {
  805.                         if(StatusMode == STATUSLINE_COMPRESSED)
  806.                         {
  807.                             Mode = MODE_SCREEN_COMPRESSED;
  808.  
  809.                             SomeObject = RPort;
  810.                         }
  811.                         else
  812.                         {
  813.                             Mode = MODE_SCREEN_NORMAL;
  814.  
  815.                             Carrier.RPort        = RPort;
  816.                             Carrier.BoxArray    = BoxArray;
  817.                             Carrier.BoxList        = BoxList;
  818.  
  819.                             SomeObject = &Carrier;
  820.                         }
  821.  
  822.                         UpdateInfo(SomeObject,Mode,INFO_ONLINETIME,0,0,0);
  823.                     }
  824.  
  825.                     memset(&DeltaTime,0,sizeof(DeltaTime));
  826.                     GetSysTime(&PeriodTime);
  827.  
  828.                         /* Keep on displaying. */
  829.  
  830.                     while(KeepGoing)
  831.                     {
  832.                             /* Are we to quit? */
  833.  
  834.                         if(SetSignal(0,SIG_KILL) & SIG_KILL)
  835.                             KeepGoing = FALSE;
  836.  
  837.                             /* Get the current time. */
  838.  
  839.                         GetSysTime(&Now);
  840.  
  841.                         SafeObtainSemaphoreShared(&OnlineSemaphore);
  842.  
  843.                             /* A connection has just
  844.                              * been established.
  845.                              */
  846.  
  847.                         if(Online && !LocalWasOnline)
  848.                         {
  849.                             OnlineTime        = Now;
  850.                             LocalWasOnline    = TRUE;
  851.                         }
  852.  
  853.                         ReleaseSemaphore(&OnlineSemaphore);
  854.  
  855.                             /* Print the current time. */
  856.  
  857.                         ThisHour    = (Now.tv_secs % (24 * 60 * 60)) / (60 * 60);
  858.                         ThisMinute    = (Now.tv_secs % (60 * 60)) / 60;
  859.  
  860.                         UpdateInfo(SomeObject,Mode,INFO_CURRENTTIME,ThisHour,ThisMinute,Now.tv_secs % 60);
  861.  
  862.                             /* Handle routine checkup actions. */
  863.  
  864.                         if(PeriodAction = (BOOL)(PeriodTime.tv_secs < Now.tv_secs && Now.tv_secs - PeriodTime.tv_secs >= ROUTINE_CHECK_INTERVAL))
  865.                         {
  866.                             PeriodTime = Now;
  867.  
  868.                             Signal((struct Task *)ThisProcess,SIG_CHECK);
  869.                         }
  870.  
  871.                         SafeObtainSemaphoreShared(&OnlineSemaphore);
  872.                         LocalIsOnline = Online;
  873.                         ReleaseSemaphore(&OnlineSemaphore);
  874.  
  875.                         if(LocalIsOnline)
  876.                         {
  877.                                 /* Show the time we have been online
  878.                                  * so far.
  879.                                  */
  880.  
  881.                             DeltaTime = Now;
  882.  
  883.                             SubTime(&DeltaTime,&OnlineTime);
  884.  
  885.                             if(Now.tv_secs != LastTime.tv_secs)
  886.                             {
  887.                                 UBYTE Sum[20];
  888.                                 WORD What;
  889.  
  890.                                 LastTime = Now;
  891.  
  892.                                 switch(Config->ScreenConfig->TimeMode)
  893.                                 {
  894.                                     case ONLINETIME_TIME:
  895.  
  896.                                         What = SHOW_OnlineTime;
  897.                                         break;
  898.  
  899.                                     case ONLINETIME_COST:
  900.  
  901.                                         What = SHOW_Cost;
  902.                                         break;
  903.  
  904.                                     case ONLINETIME_BOTH:
  905.  
  906.                                         if(PeriodAction)
  907.                                             ShowCounter = (ShowCounter + 1) % 3;
  908.  
  909.                                         switch(ShowCounter)
  910.                                         {
  911.                                             case 0:
  912.  
  913.                                                 What = SHOW_OnlineTime;
  914.                                                 break;
  915.  
  916.                                             case 1:
  917.  
  918.                                                 What = SHOW_Cost;
  919.                                                 break;
  920.  
  921.                                             case 2:
  922.  
  923.                                                 What = SHOW_UnitTime;
  924.                                                 break;
  925.                                         }
  926.  
  927.                                         break;
  928.                                 }
  929.  
  930.                                 OnlineMinutes = DeltaTime.tv_secs / 60;
  931.  
  932.                                 switch(What)
  933.                                 {
  934.                                     case SHOW_OnlineTime:
  935.  
  936.                                         UpdateInfo(SomeObject,Mode,INFO_ONLINETIME,(DeltaTime.tv_secs % 86400) / 3600,(DeltaTime.tv_secs % 3600) / 60,DeltaTime.tv_secs % 60);
  937.                                         break;
  938.  
  939.                                     case SHOW_Cost:
  940.  
  941.                                         CreateSum((QueryAccountantCost() + 5000) / 10000,TRUE,Sum,sizeof(Sum));
  942.  
  943.                                         UpdateInfo(SomeObject,Mode,INFO_ONLINECOST,Sum);
  944.                                         break;
  945.  
  946.                                     case SHOW_UnitTime:
  947.  
  948.                                         UpdateInfo(SomeObject,Mode,INFO_UNITTIME,QueryAccountantTime(NULL));
  949.                                         break;
  950.                                 }
  951.                             }
  952.                         }
  953.                         else
  954.                         {
  955.                             if(LocalWasOnline)
  956.                             {
  957.                                 LocalWasOnline = FALSE;
  958.  
  959.                                 UpdateInfo(SomeObject,Mode,INFO_ONLINETIME,(DeltaTime.tv_secs % 86400) / 3600,(DeltaTime.tv_secs % 3600) / 60,DeltaTime.tv_secs % 60);
  960.                             }
  961.                         }
  962.  
  963.                             /* Take care of the visual beep
  964.                              * if enabled.
  965.                              */
  966.  
  967.                         if(Beeping)
  968.                         {
  969.                             if(!(BeepCount--))
  970.                             {
  971.                                 Beeping = FALSE;
  972.  
  973.                                 LoadColourTable(VPort,Old,NULL,0);
  974.  
  975.                                 DeleteColourTable(Old);
  976.                                 DeleteColourTable(New);
  977.  
  978.                                 Old = New = NULL;
  979.  
  980.                                     /* Clear the signal bit. */
  981.  
  982.                                 ClrSignal(SIG_BELL);
  983.                             }
  984.                         }
  985.  
  986.                             /* Are we to show a visual beep? */
  987.  
  988.                         if(SetSignal(0,SIG_BELL) & SIG_BELL)
  989.                         {
  990.                             if(Config->TerminalConfig->BellMode == BELL_SYSTEM)
  991.                                 DisplayBeep(Window->WScreen);
  992.                             else
  993.                             {
  994.                                 if(Screen && !Config->ScreenConfig->UseWorkbench && !Beeping && (Config->TerminalConfig->BellMode == BELL_VISIBLE || Config->TerminalConfig->BellMode == BELL_BOTH))
  995.                                 {
  996.                                     if(VisualBeep(&Old,&New))
  997.                                     {
  998.                                         LoadColourTable(VPort,New,NULL,0);
  999.  
  1000.                                         Beeping = TRUE;
  1001.  
  1002.                                         BeepCount = 1;
  1003.                                     }
  1004.                                 }
  1005.                             }
  1006.                         }
  1007.  
  1008.                             /* Display the current terminal
  1009.                              * status.
  1010.                              */
  1011.  
  1012.                         if(LastStatus != GetStatus())
  1013.                             UpdateInfo(SomeObject,Mode,INFO_STATUS,LastStatus = GetStatus());
  1014.  
  1015.                             /* Show the current transfer
  1016.                              * protocol.
  1017.                              */
  1018.  
  1019.                         if(strcmp(LastProtocol,TransferProtocolName))
  1020.                         {
  1021.                             STRPTR String;
  1022.  
  1023.                             strcpy(LastProtocol,TransferProtocolName);
  1024.  
  1025.                             if(LastProtocol[0])
  1026.                                 String = LastProtocol;
  1027.                             else
  1028.                                 String = "-";
  1029.  
  1030.                             UpdateInfo(SomeObject,Mode,INFO_PROTOCOL,String);
  1031.                         }
  1032.  
  1033.                             /* Show the current baud
  1034.                              * rate.
  1035.                              */
  1036.  
  1037.                         if(LastBaud != Config->SerialConfig->BaudRate)
  1038.                             UpdateInfo(SomeObject,Mode,INFO_BAUDRATE,LastBaud = Config->SerialConfig->BaudRate);
  1039.  
  1040.                             /* Show the current
  1041.                              * terminal font.
  1042.                              */
  1043.  
  1044.                         if(LastFrozen != BufferFrozen)
  1045.                         {
  1046.                             LastFrozen = BufferFrozen;
  1047.  
  1048.                             UpdateInfo(SomeObject,Mode,INFO_BUFFER,LastFrozen != TRUE);
  1049.                         }
  1050.  
  1051.                             /* Show the current terminal
  1052.                              * emulation.
  1053.                              */
  1054.  
  1055.                         if(LastEmulation != Config->TerminalConfig->EmulationMode || (Config->TerminalConfig->EmulationMode == EMULATION_EXTERNAL && Stricmp(EmulationName,LastEmulationName)))
  1056.                         {
  1057.                             LastEmulation = Config->TerminalConfig->EmulationMode;
  1058.  
  1059.                             if(Config->TerminalConfig->EmulationMode == EMULATION_EXTERNAL)
  1060.                             {
  1061.                                 UpdateInfo(SomeObject,Mode,INFO_EMULATION,EmulationName);
  1062.  
  1063.                                 strcpy(LastEmulationName,EmulationName);
  1064.                             }
  1065.                             else
  1066.                                 UpdateInfo(SomeObject,Mode,INFO_EMULATION,ConfigEmulation[LastEmulation]);
  1067.                         }
  1068.  
  1069.                             /* Show the current serial
  1070.                              * parameters (parity, etc).
  1071.                              */
  1072.  
  1073.                         if(LastBitsPerChar != Config->SerialConfig->BitsPerChar || LastParity != Config->SerialConfig->Parity || LastStopBits != Config->SerialConfig->StopBits)
  1074.                         {
  1075.                             LastBitsPerChar    = Config->SerialConfig->BitsPerChar;
  1076.                             LastParity        = Config->SerialConfig->Parity;
  1077.                             LastStopBits    = Config->SerialConfig->StopBits;
  1078.  
  1079.                             UpdateInfo(SomeObject,Mode,INFO_PARAMETERS,LastBitsPerChar,LastParity,LastStopBits);
  1080.                         }
  1081.  
  1082.                             /* Wait another half a second. */
  1083.  
  1084.                         if(KeepGoing)
  1085.                         {
  1086.                             ULONG    Mask;
  1087.                             BOOL    ResetTime = FALSE;
  1088.  
  1089.                             StatusTimeRequest->tr_node.io_Command    = TR_ADDREQUEST;
  1090.                             StatusTimeRequest->tr_time.tv_secs        = 0;
  1091.                             StatusTimeRequest->tr_time.tv_micro        = MILLION / 2;
  1092.  
  1093.                             SetSignal(0,PORTMASK(StatusTimePort));
  1094.                             SendIO((struct IORequest *)StatusTimeRequest);
  1095.  
  1096.                             FOREVER
  1097.                             {
  1098.                                 Mask = Wait(SIG_BELL | PORTMASK(StatusTimePort) | SIG_CLOSEWINDOW | SIG_RESETTIME | UpdateMask);
  1099.  
  1100.                                 if(Mask & UpdateMask)
  1101.                                 {
  1102.                                     Signal((struct Task *)ThisProcess,SIG_HANDSHAKE);
  1103.  
  1104.                                     Wait(UpdateMask);
  1105.  
  1106.                                     NeedFullRefresh = TRUE;
  1107.  
  1108.                                     UpdateInfo(SomeObject,Mode,INFO_STATUS,LastStatus = GetStatus());
  1109.                                 }
  1110.  
  1111.                                     /* Close the window and keep quiet? */
  1112.  
  1113.                                 if(Mask & SIG_CLOSEWINDOW)
  1114.                                 {
  1115.                                     Forbid();
  1116.  
  1117.                                     ShakeHands(StatusDisplayTask,SIG_KILL);
  1118.  
  1119.                                     if(BoxList)
  1120.                                     {
  1121.                                         SZ_FreeBoxes(BoxList);
  1122.  
  1123.                                         BoxList = NULL;
  1124.                                     }
  1125.  
  1126.                                     SomeObject = NULL;
  1127.  
  1128.                                     Signal((struct Task *)ThisProcess,SIG_HANDSHAKE);
  1129.  
  1130.                                     Config->ScreenConfig->StatusLine = STATUSLINE_DISABLED;
  1131.  
  1132.                                     Permit();
  1133.                                 }
  1134.  
  1135.                                 if(Mask & SIG_BELL)
  1136.                                 {
  1137.                                     if(Config->TerminalConfig->BellMode == BELL_SYSTEM)
  1138.                                         DisplayBeep(Window->WScreen);
  1139.                                     else
  1140.                                     {
  1141.                                         if(Screen && !Config->ScreenConfig->UseWorkbench && !Beeping && (Config->TerminalConfig->BellMode == BELL_VISIBLE || Config->TerminalConfig->BellMode == BELL_BOTH))
  1142.                                         {
  1143.                                             if(VisualBeep(&Old,&New))
  1144.                                             {
  1145.                                                 LoadColourTable(VPort,New,NULL,0);
  1146.  
  1147.                                                 Beeping = TRUE;
  1148.  
  1149.                                                 BeepCount = 1;
  1150.                                             }
  1151.                                         }
  1152.                                     }
  1153.                                 }
  1154.  
  1155.                                     /* Reset the online time counter. */
  1156.  
  1157.                                 if(Mask & SIG_RESETTIME)
  1158.                                     ResetTime = TRUE;
  1159.  
  1160.                                 if(Mask & PORTMASK(StatusTimePort))
  1161.                                 {
  1162.                                     WaitIO((struct IORequest *)StatusTimeRequest);
  1163.  
  1164.                                     break;
  1165.                                 }
  1166.                             }
  1167.  
  1168.                                 /* Reset the online time. */
  1169.  
  1170.                             if(ResetTime)
  1171.                                 GetSysTime(&OnlineTime);
  1172.                         }
  1173.  
  1174.                             /* Make the colours blink. */
  1175.  
  1176.                         if(Screen && !Config->ScreenConfig->UseWorkbench && !Beeping)
  1177.                         {
  1178.                             if(Screen == IntuitionBase->FirstScreen)
  1179.                             {
  1180.                                     /* No main screen window active? */
  1181.  
  1182.                                 if(StatusWindow)
  1183.                                 {
  1184.                                     if(!(Window->Flags & WFLG_WINDOWACTIVE) && !(StatusWindow->Flags & WFLG_WINDOWACTIVE))
  1185.                                         StandardColours = TRUE;
  1186.                                 }
  1187.                                 else
  1188.                                 {
  1189.                                     if(!(Window->Flags & WFLG_WINDOWACTIVE))
  1190.                                         StandardColours = TRUE;
  1191.                                 }
  1192.  
  1193.                                     /* Menu button pressed or window disabled? */
  1194.  
  1195.                                 if(Window->Flags & (WFLG_MENUSTATE | WFLG_INREQUEST))
  1196.                                     StandardColours = TRUE;
  1197.  
  1198.                                     /* User is currently dragging the
  1199.                                      * mouse in order to mark something
  1200.                                      * on the screen?
  1201.                                      */
  1202.  
  1203.                                 if(Marking)
  1204.                                     StandardColours = TRUE;
  1205.  
  1206.                                 Background = FALSE;
  1207.                             }
  1208.                             else
  1209.                             {
  1210.                                 if(!Background)
  1211.                                     StandardColours = TRUE;
  1212.  
  1213.                                 Background = TRUE;
  1214.                             }
  1215.  
  1216.                             if(StandardColours)
  1217.                             {
  1218.                                 if(!SetColours)
  1219.                                 {
  1220.                                     LoadColourTable(VPort,NormalColourTable,NormalColours,PaletteSize);
  1221.  
  1222.                                     SetColours = TRUE;
  1223.                                 }
  1224.  
  1225.                                 StandardColours = FlashIt = FALSE;
  1226.                             }
  1227.                             else
  1228.                             {
  1229.                                     /* Are we to flash the display? */
  1230.  
  1231.                                 if(Config->ScreenConfig->Blinking)
  1232.                                 {
  1233.                                     if(Screen == IntuitionBase->FirstScreen)
  1234.                                     {
  1235.                                         if(FlashIt)
  1236.                                         {
  1237.                                             LoadColourTable(VPort,BlinkColourTable,BlinkColours,PaletteSize);
  1238.  
  1239.                                             SetColours = FALSE;
  1240.                                         }
  1241.                                         else
  1242.                                         {
  1243.                                             LoadColourTable(VPort,NormalColourTable,NormalColours,PaletteSize);
  1244.  
  1245.                                             SetColours = TRUE;
  1246.                                         }
  1247.                                     }
  1248.  
  1249.                                     FlashIt ^= TRUE;
  1250.                                 }
  1251.                             }
  1252.                         }
  1253.                     }
  1254.  
  1255.                     CloseDevice((struct IORequest *)StatusTimeRequest);
  1256.                 }
  1257.  
  1258.                 DeleteIORequest((struct IORequest *)StatusTimeRequest);
  1259.             }
  1260.  
  1261.             DeleteMsgPort(StatusTimePort);
  1262.         }
  1263.  
  1264.         if(Old)
  1265.             LoadColourTable(VPort,Old,NULL,0);
  1266.  
  1267.         DeleteColourTable(Old);
  1268.         DeleteColourTable(New);
  1269.  
  1270.         ShakeHands(StatusDisplayTask,SIG_KILL);
  1271.  
  1272.         if(BoxList)
  1273.             SZ_FreeBoxes(BoxList);
  1274.     }
  1275.  
  1276.     if(UpdateSig != -1)
  1277.         FreeSignal(UpdateSig);
  1278.  
  1279.         /* Signal the father process that we're done
  1280.          * and quietly remove ourselves.
  1281.          */
  1282.  
  1283.     Forbid();
  1284.  
  1285.     Signal((struct Task *)ThisProcess,SIG_HANDSHAKE);
  1286.  
  1287.     StatusProcess = NULL;
  1288. }
  1289.  
  1290.     /* ForceStatusUpdate():
  1291.      *
  1292.      *    Make sure that the status display gets updated
  1293.      *    as soon as possible.
  1294.      */
  1295.  
  1296. VOID
  1297. ForceStatusUpdate()
  1298. {
  1299.     if(StatusProcess && Window)
  1300.     {
  1301.         ShakeHands((struct Task *)StatusProcess,UpdateMask);
  1302.  
  1303.             /* Ok, the status process is waiting, now update the data */
  1304.  
  1305.         if(Marking)
  1306.             WindowMarkerStop();
  1307.  
  1308.         UpdateTerminalLimits();
  1309.  
  1310.             /* Clear the window */
  1311.  
  1312.         SetAPen(Window->RPort,Pens[BACKGROUNDPEN]);
  1313.         FillBox(Window->RPort,Window->BorderLeft,Window->BorderTop,Window->Width - (Window->BorderLeft + Window->BorderRight),Window->Height - (Window->BorderTop + Window->BorderBottom));
  1314.  
  1315.             /* Restart the status process */
  1316.  
  1317.         Signal((struct Task *)StatusProcess,UpdateMask);
  1318.  
  1319.             /* Repaint the window border, in case it got trashed */
  1320.  
  1321.         RefreshWindowFrame(Window);
  1322.     }
  1323. }
  1324.